package com.hollysys.inspection.utils;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.crypto.SecureUtil;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Objects;

@Slf4j
public class RtspUtil {

    // LFU(least frequently used) 最少使用率策略，一分钟后未使用超时删除
    private static final Cache<String, FFmpegFrameGrabber> LFU_CACHE = CacheUtil.newLFUCache(10, 60 * 1000);

    static {
        LFU_CACHE.setListener((key, grabber) -> {
            try {
                grabber.stop();
            } catch (FFmpegFrameGrabber.Exception e) {
                log.error("FFmpegFrameGrabber停止出现异常，key = {}", key);
            }
        });
    }

    public static void captureFrame(String rtspUrl, String outputPath) {
        TimeInterval timer = DateUtil.timer();
        String key = SecureUtil.md5(rtspUrl);
        FFmpegFrameGrabber grabber = LFU_CACHE.get(key);
        if (Objects.isNull(grabber)) {
            grabber = new FFmpegFrameGrabber(rtspUrl);
        }

        try (Java2DFrameConverter converter = new Java2DFrameConverter()) {
            // 关键参数设置
            grabber.start();
            grabber.flush();
            // 获取一帧
            Frame frame = grabber.grabImage();
            if (frame != null) {
                BufferedImage image = converter.convert(frame);
                ImageIO.write(image, "JPEG", new File(outputPath));
                log.info("图片提取成功，time : {}， 路径 : {}", frame.timestamp, outputPath);
                grabber.stop();
            } else {
                grabber.stop();
                log.error("未能获取图像，rtspUrl：{}", rtspUrl);
                throw new RuntimeException("未能获取图像");
            }
        } catch (Exception e) {
            log.error("获取图像出现异常，rtspUrl：{}", rtspUrl, e);
            throw new RuntimeException("获取图像出现异常");
        } finally {
            long intervalRestart = timer.intervalRestart();
            log.info("截图耗时：{}毫秒", intervalRestart);
        }
    }

    // public static List<String> captureFrames(String rtspUrl) {
    //     TimeInterval timer = DateUtil.timer();
    //     List<String> list = new ArrayList<>();
    //     try (FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtspUrl);
    //          Java2DFrameConverter converter = new Java2DFrameConverter()) {
    //         grabber.start();
    //         grabber.flush();
    //         for (int i = 0; i < 10; i++) {
    //             // 获取一帧
    //             Frame frame = grabber.grabImage();
    //             if (frame != null) {
    //                 BufferedImage image = converter.convert(frame);
    //                 String outputPath = "pic/" + i + "snapshot_javacv.jpg";
    //                 ImageIO.write(image, "JPEG", new File(outputPath));
    //                 log.info("图片提取成功，time : {}， 路径 : {}", frame.timestamp, outputPath);
    //             }
    //         }
    //     } catch (Exception e) {
    //         log.error("获取图像出现异常，rtspUrl：{}", rtspUrl, e);
    //         throw new RuntimeException("获取图像出现异常");
    //     } finally {
    //         long intervalRestart = timer.intervalRestart();
    //         log.info("截图耗时：{}毫秒", intervalRestart);
    //     }
    //     return list;
    // }

    // public static void captureRtspFrame(String rtspUrl, String outputPath) {
    //     FileUtil.mkParentDirs(outputPath);
    //
    //     // FFmpeg命令：从RTSP流中截取第一帧保存为JPEG
    //     String command = String.format(
    //             "ffmpeg -y -i %s -frames:v 1 -q:v 2 -f image2 %s",
    //             rtspUrl, outputPath
    //     );
    //     System.out.println(command);
    //     try {
    //         Process process = Runtime.getRuntime().exec(command);
    //         // 读取错误流（FFmpeg输出到stderr）
    //         BufferedReader errorReader = new BufferedReader(
    //                 new InputStreamReader(process.getErrorStream())
    //         );
    //         String line;
    //         while ((line = errorReader.readLine()) != null) {
    //             // System.out.println(line); // 打印FFmpeg日志
    //         }
    //         int exitCode = process.waitFor();
    //         if (exitCode == 0) {
    //             System.out.println("截图保存成功: " + outputPath);
    //         } else {
    //             System.err.println("截图失败，FFmpeg退出码: " + exitCode);
    //         }
    //     } catch (IOException | InterruptedException e) {
    //         e.printStackTrace();
    //     }
    // }

}
